﻿// -----------------------------------------------------------------------
// <copyright file="IdealFilter.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace ImageP
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    using FourierFin;
    using MathWorks.MATLAB.NET.Arrays;
    using MathWorks.MATLAB.NET.Utility;
    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class IdealFilter
    {
        Normalize norm = new Normalize();
        public int[,] normalizedBufferRed, normalizedBufferGreen, normalizedBufferBlue;
        public RGBcolor[,] realImage;
        public FourierT ft = new FourierT();
        public MWArray realF, inverseFreqR, inverseFreqG, inverseFreqB;
        public double[,] realBufferR, realBufferG, realBufferB, imgBufferR, imgBufferG, imgBufferB, D, H, realR, realG, realB;
        public Bitmap bm;
        public Bitmap LowpassIdeal(Bitmap Buffer, double Do)
        {

            normalizedBufferRed = new int[Buffer.Height, Buffer.Width];
            normalizedBufferGreen = new int[Buffer.Height, Buffer.Width];
            normalizedBufferBlue = new int[Buffer.Height, Buffer.Width];
            byte[,] R = new byte[Buffer.Height, Buffer.Width];
            byte[,] G = new byte[Buffer.Height, Buffer.Width];
            byte[,] B = new byte[Buffer.Height, Buffer.Width];
            bm = new Bitmap(Buffer.Width, Buffer.Height);

            Color Clr;
            for (int i = 0; i < Buffer.Height; i++)
            {
                for (int j = 0; j < Buffer.Width; j++)
                {
                    Clr = Buffer.GetPixel(j, i);
                    R[i, j] = Clr.R;
                    G[i, j] = Clr.G;
                    B[i, j] = Clr.B;
                }
            }


            MWArray ftsR, ftsG, ftsB;
            ftsR = (MWNumericArray)ft.FreqDomian((MWNumericArray)R);
            ftsG = (MWNumericArray)ft.FreqDomian((MWNumericArray)G);
            ftsB = (MWNumericArray)ft.FreqDomian((MWNumericArray)B);

            realBufferR = (double[,])ft.getReal(ftsR).ToArray();
            realBufferG = (double[,])ft.getReal(ftsG).ToArray();
            realBufferB = (double[,])ft.getReal(ftsB).ToArray();

            imgBufferR = (double[,])ft.getImag(ftsR).ToArray();
            imgBufferG = (double[,])ft.getImag(ftsG).ToArray();
            imgBufferB = (double[,])ft.getImag(ftsB).ToArray();

            D = new double[Buffer.Height, Buffer.Width];
            H = new double[Buffer.Height, Buffer.Width];
            for (int i = 0; i < Buffer.Height; i++)
            {
                for (int j = 0; j < Buffer.Width; j++)
                {
                    //D[i, j] = Math.Sqrt(Math.Pow(i - Buffer.Width / 2, 2) + Math.Pow(j - Buffer.Height / 2, 2));

                    if (Math.Sqrt(Math.Pow(j - Buffer.Width / 2, 2) + Math.Pow(i - Buffer.Height / 2, 2)) <= Do)
                    {
                        H[i, j] = 1;
                    }
                    else
                        H[i, j] = 0;
                }
            }
            for (int i = 0; i < Buffer.Height; i++)
            {
                for (int j = 0; j < Buffer.Width; j++)
                {
                    realBufferR[i, j] = realBufferR[i, j] * H[i, j];
                    realBufferG[i, j] = realBufferG[i, j] * H[i, j];
                    realBufferB[i, j] = realBufferB[i, j] * H[i, j];

                    imgBufferR[i, j] = imgBufferR[i, j] * H[i, j];
                    imgBufferG[i, j] = imgBufferG[i, j] * H[i, j];
                    imgBufferB[i, j] = imgBufferB[i, j] * H[i, j];

                }
            }



            //inverse
            inverseFreqR = (MWArray)ft.InvF((MWNumericArray)realBufferR, (MWNumericArray)imgBufferR);
            inverseFreqG = (MWArray)ft.InvF((MWNumericArray)realBufferG, (MWNumericArray)imgBufferG);
            inverseFreqB = (MWArray)ft.InvF((MWNumericArray)realBufferB, (MWNumericArray)imgBufferB);
            realR = (double[,])inverseFreqR.ToArray();
            realG = (double[,])inverseFreqG.ToArray();
            realB = (double[,])inverseFreqB.ToArray();


            normalizedBufferRed = norm.Normalize_imagefft(realR, Buffer.Height, Buffer.Width);
            normalizedBufferGreen = norm.Normalize_imagefft(realG, Buffer.Height, Buffer.Width);
            normalizedBufferBlue = norm.Normalize_imagefft(realB, Buffer.Height, Buffer.Width);



            for (int i = 0; i < Buffer.Height; i++)
            {
                for (int j = 0; j < Buffer.Width; j++)
                {

                    bm.SetPixel(j, i, System.Drawing.Color.FromArgb(normalizedBufferRed[i, j], normalizedBufferGreen[i, j], normalizedBufferBlue[i, j]));

                }
            }
            return bm;
        }


        //High
        public Bitmap HighpassIdeal(Bitmap Buffer, double Do)
        {
            normalizedBufferRed = new int[Buffer.Height, Buffer.Width];
            normalizedBufferGreen = new int[Buffer.Height, Buffer.Width];
            normalizedBufferBlue = new int[Buffer.Height, Buffer.Width];
            byte[,] R = new byte[Buffer.Height, Buffer.Width];
            byte[,] G = new byte[Buffer.Height, Buffer.Width];
            byte[,] B = new byte[Buffer.Height, Buffer.Width];
            bm = new Bitmap(Buffer.Width, Buffer.Height);

            Color Clr;
            for (int i = 0; i < Buffer.Height; i++)
                for (int j = 0; j < Buffer.Width; j++)
                {
                    Clr = Buffer.GetPixel(j, i);
                    R[i, j] = Clr.R;
                    G[i, j] = Clr.G;
                    B[i, j] = Clr.B;
                }


            MWArray ftsR, ftsG, ftsB;
            ftsR = (MWNumericArray)ft.FreqDomian((MWNumericArray)R);
            ftsG = (MWNumericArray)ft.FreqDomian((MWNumericArray)G);
            ftsB = (MWNumericArray)ft.FreqDomian((MWNumericArray)B);

            realBufferR = (double[,])ft.getReal(ftsR).ToArray();
            realBufferG = (double[,])ft.getReal(ftsG).ToArray();
            realBufferB = (double[,])ft.getReal(ftsB).ToArray();

            imgBufferR = (double[,])ft.getImag(ftsR).ToArray();
            imgBufferG = (double[,])ft.getImag(ftsG).ToArray();
            imgBufferB = (double[,])ft.getImag(ftsB).ToArray();

            D = new double[Buffer.Height, Buffer.Width];
            H = new double[Buffer.Height, Buffer.Width];
            for (int i = 0; i < Buffer.Height; i++)
            {
                for (int j = 0; j < Buffer.Width; j++)
                {


                    D[i, j] = Math.Sqrt(Math.Pow(j - Buffer.Width / 2, 2) + Math.Pow(i - Buffer.Height / 2, 2));
                    if (D[i, j] <= Do)
                    {
                        H[i, j] = 0;

                    }
                    else
                        H[i, j] = 1;
                }
            }
            for (int i = 0; i < Buffer.Height; i++)
            {
                for (int j = 0; j < Buffer.Width; j++)
                {
                    realBufferR[i, j] = realBufferR[i, j] * H[i, j];
                    realBufferG[i, j] = realBufferG[i, j] * H[i, j];
                    realBufferB[i, j] = realBufferB[i, j] * H[i, j];

                    imgBufferR[i, j] = imgBufferR[i, j] * H[i, j];
                    imgBufferG[i, j] = imgBufferG[i, j] * H[i, j];
                    imgBufferB[i, j] = imgBufferB[i, j] * H[i, j];

                }
            }



            //inverse
            inverseFreqR = (MWArray)ft.InvF((MWNumericArray)realBufferR, (MWNumericArray)imgBufferR);
            inverseFreqG = (MWArray)ft.InvF((MWNumericArray)realBufferG, (MWNumericArray)imgBufferG);
            inverseFreqB = (MWArray)ft.InvF((MWNumericArray)realBufferB, (MWNumericArray)imgBufferB);
            realR = (double[,])inverseFreqR.ToArray();
            realG = (double[,])inverseFreqG.ToArray();
            realB = (double[,])inverseFreqB.ToArray();



            normalizedBufferRed = norm.Normalize_imagefft(realR, Buffer.Height, Buffer.Width);
            normalizedBufferGreen = norm.Normalize_imagefft(realG, Buffer.Height, Buffer.Width);
            normalizedBufferBlue = norm.Normalize_imagefft(realB, Buffer.Height, Buffer.Width);

            for (int i = 0; i < Buffer.Height; i++)
            {
                for (int j = 0; j < Buffer.Width; j++)
                {
                    bm.SetPixel(j, i, System.Drawing.Color.FromArgb(normalizedBufferRed[i, j], normalizedBufferGreen[i, j], normalizedBufferBlue[i, j]));
                }
            }
            return bm;
        }
    }
}
